#coding=utf8
import re, threading

from utils.importUtils import import_module
from ws_setting import core_logger

class FilterChain:
    def __init__(self):
        self._lock = threading.Lock()


    def process(self, session, *args, **kargs):
        """
            start filter chain
        """
        core_logger.debug("########## in FilterChain process ##########")
        # when execute onopen method after session created,
        # there are two threads which are the main thread and the connector thread to visit the new session filterChain ,
        # lock this block to make sure the main thread have priority 
        if self._lock.acquire():
            try:
                core_logger.debug("########## thread %s obtain lock #########" % threading.currentThread().getName())
                _current_filter = self.first_filter
                _current_filter.before_process(session, *args, **kargs)

                while getattr(_current_filter, "next", ""):
                    _current_filter = _current_filter.next
                    _current_filter.before_process(session, *args, **kargs)

                #using suitable method execute

                if session.process_function:
                    processes = list()

                    if type(session.process_function) == list:
                        # accept many websocket request within a very short period of time, many request will be merged by "\xff\x00" in websocket protocol 00
                        processes = session.process_function
                    else:
                        processes.append(session.process_function)

                    for proc in processes:
                        response = proc(session.request)
                        while _current_filter:
                            _current_filter.after_process(session, response, *args, **kargs)
                            if hasattr(_current_filter, "prev"):
                                _current_filter = _current_filter.prev
                            else:
                                break
                    else:
                        core_logger.warn("no suitable method execute")
            finally:
                session.clean()
                core_logger.debug("########## thread %s release lock #########" % threading.currentThread().getName())
                self._lock.release()

    def init_filter(self, filters):
        pattern = re.compile("(.+)\.(\w+)$")
        prev_filter = None
        for registed_filter in filters:
            module_name, classObj = pattern.match(registed_filter).groups() #import module
            filter_module = import_module(module_name)
            core_logger.debug("import filter module from module_name {}".format(module_name)) 
            filter_instance = getattr(filter_module, classObj)()
            if filter_instance:
                self.validate_filter_instance(filter_instance)
                if prev_filter:
                    filter_instance.prev = prev_filter
                    prev_filter.next = filter_instance
                else:
                    prev_filter = filter_instance
                    self.first_filter = filter_instance
            else:
                raise ValueError("找不到注册的module {}".format(registed_filter))

    def initialization(self, module):
        """
            initialize filter chain
        """
        self.init_filter(module.filters)


    def validate_filter_instance(self, anyfilter):
        pass



